import React, { PureComponent } from 'react'
import { connect } from '@umijs/max'
import { Button, Form, Input, message, Modal, Select, Spin, Tooltip, TreeSelect } from 'antd'
import list2tree from 'list2tree'
import { ExclamationCircleFilled } from '@ant-design/icons'
import Tools from '@/utils/Tools'
import { HufuTreeTitle, ProTree, searchTreeListByName } from '@/components'
import { TreeIcon } from '../../../../components'
import styles from './index.less'
import {
  deleteTask,
  devDirChange,
  getDirTree,
  getFunctionDetail,
  getTrees,
  listResource,
  saveDir,
  saveFunction
} from './api'

const Bus = Tools.Bus
const { Item } = Form
const { Option } = Select
const { TextArea } = Input
const isDir = (nodeType) => [0, 1, 2, 3, 4].includes(nodeType)
const getNavTreeDataFunc = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'name',
  },
})
const setCopy = function (val, showMessage = true) {
  const input = document.createElement('textarea')
  input.innerHTML = val || ''
  document.body.appendChild(input)
  input.select()
  const result = document.execCommand('copy')
  document.body.removeChild(input)
  showMessage && message.success('复制成功')
  return result
}
/**
 * 数据开发任务类型 ----------------------------nodeType-----------------------------------
 * 0：普通目录
 * 1：工作流程目录
 * 2：数据集成目录
 * 3：数据开发目录
 * 4：数据质量目录
 * 10：资源
 * 11：函数
 * 12：开始节点
 * 13：sql
 * 14：mr
 * 15：impala
 * 16：shell
 * 17：python2
 * 18：python3
 * 19：pyspark
 * 20：离线同步
 * 21：接口采集
 * 22：数据质量
 * */

@connect(({ scriptDev }) => ({ ...scriptDev }))
export default class DataDevTree extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      // expandArr: [],
      modifyId: null,
      isShowTask: false,
      navListSpinning: false,
      isShowFiles: false,
      searchValue: '',
      treeOption: [],
      resourceOption: [],
      treeLists: [],
      treeDataNew: [],
      fItem: null,
      cItem: null,
      isShowDetail: false,
    }

    this.taskForm = React.createRef()
    this.fileForm = React.createRef()
    this.detailForm = React.createRef()
  }

  componentDidMount() {
    this.refresh()
    Bus.addListener('ShowFunctionModal', this.showTaskModal)
    Bus.addListener('RefreshDevTree', this.refresh)
  }

  componentWillUnmount() {
    Bus.removeListener('ShowFunctionModal', this.showTaskModal)
    Bus.removeListener('RefreshDevTree', this.refresh)
  }

  // 获取树状列表
  getTreeList = () => {
    this.setState({ navListSpinning: true })
    getTrees({ id: 4 }).then(
      (res) => {
        this.setState({
          navListSpinning: false,
          treeLists: res,
          treeDataNew: getNavTreeDataFunc(res),
        })
      },
      (error) => {
        this.setState({ navListSpinning: false })
      },
    )
  }

  // 获取目录选项列表
  getDirTreeOption = () => {
    getDirTree({ id: 4 }).then(
      (res) => {
        if (res && res[0]) {
          const { childs } = res[0]
          this.setState({
            treeOption: childs,
          })
        } else {
          this.setState({
            treeOption: [],
          })
        }
      },
      (error) => {
        console.log(error)
      },
    )
  }

  // 获取资源选项
  getResourceOption = () => {
    getTrees({ id: 3 }).then(
      (res) => {
        const arr = res.map((item) => ({
          disabled: item.nodeType !== 10,
          ...item,
        }))
        this.setState({
          resourceOption: getNavTreeDataFunc(arr),
        })
      },
      (error) => {
        console.log(error)
      },
    )
    // listResource().then(
    //   (res) => {
    //     if (res) {
    //       this.setState({
    //         resourceOption: res,
    //       })
    //     } else {
    //       this.setState({
    //         resourceOption: [],
    //       })
    //     }
    //   },
    //   (error) => {
    //     console.log(error)
    //   },
    // )
  }

  // 打开新建目录弹窗
  showFilesModal = (id) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: null,
      isShowFiles: true,
    }, () => {
      if (id) {
        this.fileForm.current.setFieldsValue({ pid: id })
      }
    })
  }

  // 编辑打开新建目录弹窗
  editFilesModal = (item) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: item.id,
      isShowFiles: true,
    }, () => {
      if (item) {
        this.fileForm.current.setFieldsValue({
          pid: item.pid == '4' ? undefined : item.pid,
          name: item.name,
        })
      }
    })
  }

  // 打开新建工作弹窗
  showTaskModal = (item, pid) => {
    this.taskForm.current?.resetFields()
    this.setState({
      modifyId: item ? item.id : null,
      isShowTask: true,
    }, () => {
      if (item) {
        this.taskForm.current.setFieldsValue({
          pid: (item.pid && item.pid != '4') ? item.pid : undefined,
          functionName: item.name,
          ...item,
        })
      } else if (pid) {
        this.taskForm.current.setFieldsValue({ pid })
      }
    })
  }

  // 编辑打开弹窗
  editTaskModal = (item) => {
    this.setState({ navListSpinning: true })
    getFunctionDetail({
      nodeId: item.id,
    }).then(
      (res) => {
        this.setState({
          modifyId: item.id,
          isShowTask: true,
          navListSpinning: false,
        }, () => {
          this.taskForm.current.setFieldsValue({
            pid: (item.pid && item.pid != '4') ? item.pid : undefined,
            ...res,
          })
        })
      },
      (error) => {
        this.setState({ navListSpinning: false })
      },
    )
  }

  // 刷新
  refresh = () => {
    this.getTreeList()
    this.getDirTreeOption()
    this.getResourceOption()
  }

  renderTreeNodes = (data) => {
    const tempArr = []
    data.map((item) => {
      const {
        name, id, nodeType,
      } = item
      const defaultIconFun = props => {
        const { selectedKeys } = this.state
        if (selectedKeys && selectedKeys[0] == props.data.key) {
          return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakaihover" /> : <i className="iconfont-colour2 icon-wenjianjia-morenhover" />
        }
        return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakai" /> : <i className="iconfont-colour2 icon-wenjianjia-moren" />
      }
      const icon = item.nodeType == 0 ? defaultIconFun : <TreeIcon color="yellow" iconName="icon-hanshu1" />
      const tempObj = {
        icon,
        key: id,
        nodeType,
      }
      tempObj.title = (
        <HufuTreeTitle
          title={name}
          key={item.id}
          icon
          operations={[
            isDir(item.nodeType) ? (
              <span
                key={`newDir${item.id}`}
                onClick={() => this.showFilesModal(item.id)}
              >
                新建目录
              </span>
            ) : null,
            isDir(item.nodeType) ? (
              <span
                key={`new${item.id}`}
                onClick={() => this.showTaskModal(null, item.id)}
              >
                新建函数
              </span>
            ) : null,
            <span
              key={`edit${item.id}`}
              onClick={() => (isDir(item.nodeType) ? this.editFilesModal(item) : this.editTaskModal(item))}
            >
              编辑
            </span>,
            <span
              key={`del${item.id}`}
              onClick={() => {
                Modal.confirm({
                  title: '确认要删除这个任务吗？',
                  icon: <ExclamationCircleFilled />,
                  content: '删除后数据将无法恢复，请谨慎操作',
                  okText: '删除',
                  cancelText: '取消',
                  okButtonProps: {
                    danger: true,
                  },
                  onOk: () => {
                    this.setState({ navListSpinning: true })
                    deleteTask({ id: item.id }).then(
                      (res) => {
                        message.success('删除成功')
                        this.refresh()
                      },
                      (error) => {
                        this.setState({ navListSpinning: false })
                      },
                    )
                  },
                })
              }}
            >
              删除
            </span>,
          ]}
        />
      )
      if (item.children) {
        tempObj.children = this.renderTreeNodes(item.children)
      }
      tempArr.push(tempObj)
    })
    return tempArr
  }

  onDragEnter = (opt) => {

    // if ([0, 3].indexOf(opt.node.props.data.nodeType) > -1) {
    //   this.setState({
    //     expandArr: opt.expandedKeys,
    //   })
    // }
  }

  onDrop = (opt) => {
    if (!opt.dropToGap) {
      this.setState(
        {
          cItem: opt.dragNode.props.data,
          fItem: opt.node.props.data,
        },
        this.catalogChange,
      )
    } else {
      this.setState(
        {
          cItem: opt,
        },
        // this.datadevDirSort,
      )
    }
  }

  // 拖动
  catalogChange = () => {
    const cItem = this.state.cItem
    const fItem = this.state.fItem
    const noChange = (isDir(fItem.nodeType)
      && [fItem.nodeType, 13, 14, 15, 16, 17, 18, 19].includes(cItem.nodeType))
      || (isDir(fItem.nodeType) && fItem.nodeType == cItem.nodeType)
      || (isDir(fItem.nodeType) && cItem.nodeType == 20 && fItem.nodeType == 2)
      || (isDir(fItem.nodeType) && cItem.nodeType == 21 && fItem.nodeType == 2)
      || (isDir(fItem.nodeType) && cItem.nodeType == 3 && fItem.nodeType == 3)
    if (noChange) {
      devDirChange({
        pid: fItem.key,
        id: cItem.key,
      }).then(
        (res) => {
          message.success('修改成功')
          // 当修改完成后，由于可以跨层级拖动，所以为了保险所有的工作流都要刷新
          this.refresh()
        },
        (error) => {
          console.log(error)
        },
      )
    } else {
      message.warning('此文件不能移动到此目录下')
    }
  }

  // 新建目录确认
  filesOnOk = () => {
    this.fileForm.current.validateFields().then(values => {
      this.setState({ navListSpinning: true })
      if (this.state.modifyId) {
        values.id = this.state.modifyId
      }
      if (!values.pid) values.pid = 4
      saveDir(values).then(
        (res) => {
          message.success(this.state.modifyId ? '修改目录成功' : '新建目录成功')
          this.setState({
            isShowFiles: false,
            navListSpinning: false,
          }, () => {
            this.refresh()
          })
        },
        (error) => {
          this.setState({ navListSpinning: false })
        },
      )
    })
  }

  // 新建函数确认
  taskOnOk = () => {
    this.taskForm.current.validateFields().then(values => {
      this.setState({ navListSpinning: true })
      if (!values.pid) values.pid = 4
      const postObj = {
        nodeName: values.functionName,
        ...values,
      }
      if (this.state.modifyId) {
        postObj.nodeId = this.state.modifyId
      }
      saveFunction(postObj).then(
        (res) => {
          message.success(this.state.modifyId ? '修改函数成功' : '新建函数成功')
          this.setState({
            isShowTask: false,
            navListSpinning: false,
          }, () => {
            this.refresh()
          })
        },
        (error) => {
          this.setState({ navListSpinning: false })
        },
      )
    })
  }

  // 树状列表选择回调
  onSelect = (selectedKeys) => {
    this.setState({
      selectedKeys,
    }, () => {
      if (selectedKeys.length > 0) {
        const { treeLists } = this.state
        const obj = treeLists.find((item) => item.id == selectedKeys[0])
        if (obj && obj.nodeType == 4) {
          this.setState({ navListSpinning: true })
          getFunctionDetail({
            nodeId: obj.id,
          }).then(
            (res) => {
              this.setState({
                modifyId: obj.id,
                isShowDetail: true,
                navListSpinning: false,
                resourcePath: res.resourcePath,
              }, () => {
                this.detailForm.current.setFieldsValue(res)
              })
            },
            (error) => {
              this.setState({ navListSpinning: false })
            },
          )
        }
      }
    })
  }

  render() {
    const {
      treeOption, searchValue, resourceOption, treeLists, isShowDetail, selectedKeys, treeDataNew,
    } = this.state
    const {
      title,
    } = this.props
    return (
      <div
        className={`${styles.script_dev}`}
      // style={{ display: this.props.navKey == 0 ? 'block' : 'none' }}
      >
        <Spin spinning={this.state.navListSpinning}>
          <div className={styles.datadev_tree_box}>
            <ProTree
              onExpand={this.onExpand}
              // expandedKeys={this.state.expandArr}
              selectedKeys={selectedKeys}
              showSearch
              onDragEnter={this.onDragEnter}
              onDrop={this.onDrop}
              // draggable
              onSelect={this.onSelect}
              title={title || '目录'}
              operations={[
                <i
                  key="1"
                  className="iconfont icon-xinjianwenjianjia"
                  onClick={() => this.showFilesModal(null)}
                />,
                <i
                  key="2"
                  className="iconfont icon-tianjia"
                  onClick={() => this.showTaskModal(null)}
                />,
              ]}
              renderTreeNodes={this.renderTreeNodes}
              treeData={treeDataNew}
              ref={(dev) => (this.tree = dev)}
              search={(name) => {
                const searchTree = searchTreeListByName(
                  name,
                  treeLists,
                )
                const treeDataNews = getNavTreeDataFunc(
                  searchTree.result,
                )
                this.setState(
                  {
                    treeDataNew: treeDataNews,
                  },
                  () => {
                    this.tree.onExpand(searchTree.fatchIds)
                  },
                )
              }}
            />
          </div>
        </Spin>
        <Modal
          title={this.state.modifyId ? '修改目录' : '新建目录'}
          visible={this.state.isShowFiles}
          confirmLoading={this.state.navListSpinning}
          cancelText="取消"
          okText="保存"
          onOk={this.filesOnOk}
          onCancel={() => {
            this.setState({
              isShowFiles: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.fileForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="目录名称"
                name="name"
                rules={[
                  { required: true, message: '请输入目录名称' },
                ]}
              >
                <Input placeholder="请输入目录名称" />
              </Item>
              <Item
                label="父级目录"
                name="pid"
              >
                <TreeSelect
                  allowClear
                  showSearch
                  getPopupContainer={(triggerNode) => triggerNode.parentNode}
                  // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                  treeData={treeOption}
                  placeholder="请选择父级目录"
                  treeDefaultExpandAll
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  fieldNames={{
                    label: 'name', value: 'id', children: 'childs',
                  }}
                />
              </Item>
            </Form>
          </div>
        </Modal>
        <Modal
          title={
            this.state.modifyId
              ? '编辑函数'
              : '新建函数'
          }
          confirmLoading={this.state.navListSpinning}
          visible={this.state.isShowTask}
          cancelText="取消"
          okText="确定"
          onOk={this.taskOnOk}
          onCancel={() => {
            this.setState({
              isShowTask: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.taskForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="函数名称"
                name="functionName"
                rules={[
                  { required: true, message: '请输入资源名称' },
                ]}
              >
                <Input placeholder="请输入资源名称" />
              </Item>
              <Item
                label="类名"
                name="className"
                rules={[
                  { required: true, message: '请输入类名' },
                ]}
              >
                <Input placeholder="请输入类名" />
              </Item>
              <Item
                label="资源"
                name="resourceNodeId"
                rules={[
                  { required: true, message: '请选择资源' },
                ]}
              >
                <TreeSelect
                  allowClear
                  showSearch
                  getPopupContainer={(triggerNode) => triggerNode.parentNode}
                  treeData={resourceOption}
                  placeholder="请选择资源"
                  treeDefaultExpandAll
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  fieldNames={{
                    label: 'name', value: 'id', children: 'children',
                  }}
                />
              </Item>
              <Item
                label="用途"
                name="usedDesc"
              >
                <Input placeholder="请输入用途" />
              </Item>
              <Item
                label="命令格式"
                name="format"
                rules={[
                  { required: true, message: '请输入命令格式' },
                ]}
              >
                <TextArea
                  placeholder="请输入命令格式"
                  rows={3}
                />
              </Item>
              <Item
                label="父级目录"
                name="pid"
              >
                <TreeSelect
                  allowClear
                  showSearch
                  getPopupContainer={(triggerNode) => triggerNode.parentNode}
                  // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                  treeData={treeOption}
                  placeholder="请选择父级目录"
                  treeDefaultExpandAll
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  fieldNames={{
                    label: 'name', value: 'id', children: 'childs',
                  }}
                />
              </Item>
              <Item
                label="参数说明"
                name="paramDesc"
              >
                <TextArea
                  placeholder="请输入参数说明"
                  rows={3}
                />
              </Item>
            </Form>
          </div>
        </Modal>
        <Modal
          title="函数详情"
          confirmLoading={this.state.navListSpinning}
          visible={isShowDetail}
          footer={null}
          onCancel={() => {
            this.setState({
              isShowDetail: false,
            })
          }}
        >
          <Form
            ref={this.detailForm}
            labelCol={{ span: 5 }}
            wrapperCol={{ span: 19 }}
            autoComplete="off"
          >
            <Item
              label="函数名称"
              name="functionName"
            >
              <Input disabled />
            </Item>
            <Item
              label="用途"
              name="purpose"
            >
              <Input disabled />
            </Item>
            <Item
              label="命令格式"
              name="format"
            >
              <TextArea
                rows={3}
                disabled
              />
            </Item>
            <Item
              label="创建时间"
              name="createTime"
            >
              <Input disabled />
            </Item>
            <Item
              label="最近修改时间"
              name="updateTime"
            >
              <Input disabled />
            </Item>
            <Item
              label="资源路径"
            >
              <Input.Group compact className={styles.resource_input}>
                <Item
                  noStyle
                  name="resourcePath"
                >
                  <Input
                    disabled
                  />
                </Item>
                <Tooltip title="复制资源路径">
                  <Button
                    icon={<i className="iconfont icon-fuzhi" />}
                    onClick={
                      () => {
                        setCopy(this.state.resourcePath)
                      }
                    }
                  />
                </Tooltip>
              </Input.Group>
            </Item>
            <Item
              label="参数说明"
              name="paramDesc"
            >
              <TextArea
                rows={3}
                disabled
              />
            </Item>
          </Form>
        </Modal>
      </div>
    )
  }
}
